require 'rubygems'
require 'ruby-debug'
require 'dict'
require 'jcode'
require 'iconv'

#TODO 
#1. 清除头尾的未成对的符合
#2. 清除开头及结尾的符号
$KCODE='u'
class ClearTaobaoTitle

	#英文及数字在title最大比例
	ENG_NUM_RATE = 0.4
	
	attr_reader :key_verify
	attr_reader :stop
	
	def initialize(params = {})
		@title = params[:title]
		@good_no = params[:good_no]
		@nick = params[:nick]
		@num_iid = params[:num_iid]
		
		@key_verify = false
		@stop = false
		
		output_file = "result.log"
		@log = open(output_file, (File::WRONLY | File::APPEND | File::CREAT))
		@log.puts "[source]num_iid:#{@num_iid};\ntitle:#{@title};\ngood_no:#{@good_no};\nnick:#{@nick}"
	end
	
  def filter()
  	return "" if deal_stop(@title)
  	
  	@stop = eng_num_rate()
    return "" if @stop
  	
    before_filter()
    #puts "before:#{@title}"
    @log.puts "before:#{@title}"
    
    clear_good_no()
    #puts "clear goodNo:#{@title};verify:#{@key_verify}"
    @log.puts "clear goodNo:#{@title};verify:#{@key_verify}"
    
    replace_by_regexp()
    #puts "regexp:#{@title}"
    @log.puts "regexp:#{@title}"
    
    replace_by_keyword()
    #puts "keyword:#{@title}"
    @log.puts "keyword:#{@title}"
    
    clear_addition()
    #puts "clear addition:#{@title}"
		@log.puts "clear addition:#{@title}"    
    
    replace_by_nick()
    #puts "nick:#{@title}"
    @log.puts "nick:#{@title}"
    
    #clear_doubtful()
    #puts "doubtful:#{@title}"
    #@log.puts "doubtful:#{@title}"
    
    clear_split_word()
    @log.puts "split word:#{@title}"
    
    clear_no_pairs_punctuation()
    @log.puts "no pairs punctuation:#{@title}"
    
    clear_start_or_end_punctuation
    @log.puts "start or end punctuation:#{@title}"
    
    after_filter()
    @log.puts "after:#{@title}\n\n"
    @log.close
    @title
  end
  
  #核心过滤前处理
  def before_filter()
  	@title = @title.gsub(/&\w+;/, "")
  	@title = clear_special(@title)
  	@title = invert_number(@title)  
  end
  
  #核心过滤完后处理
  def after_filter()
		Dict::INVERT_WORDS.each do |v| 
			mat_ret = @title.match(/(\d{1}(00)?)#{v}/i)
			#debugger
			next if mat_ret.nil?
			
			invert_num = Dict::NUM_MAP.invert[mat_ret[1]]
			@title = @title.gsub("#{mat_ret[1] + v}", "#{invert_num + v}")
		end 	
		@title = @title.strip
		@title = @title.gsub("()", "")
		@title = @title.gsub(/(^\d+)|(\d+$)/, "").strip #去除以数字开头的数字(非2010开头)
		#@title = @title.gsub(/(^\d+[a-zA-z]+|^[a-zA-z]+\d+)/, "") #去除以数字加字母组合的开头
		@key_verify = true if @title.length < 20
  	@title
  end

  #使用正则清除垃圾字符
  def clear_special(title = "")
    return title.gsub(Dict::RUBBISH_WORDS_REG, " ")
  end
  
  #将单词按空格划分后,单个词判断
  def clear_split_word()
	  @title = @title.gsub(/\s+/, " ")
  	titles = @title.split(/\s+/)
  	ret = []
  	titles.each do |t|
  		next if t.nil?
  		next if t.jlength == 1
			next if t =~ /^[0-9a-zA-Z_]+$/ && t != "2010" #如果该词由数字+英文或下划线组成的过滤掉
			
			ret << t
  	end
  	@title = ret.join(" ")
  end
  
  #清除例如：含、不含、送之类的附加字符
  def clear_addition()
  	Dict::ADDIT_WORDS.each do |addit|
  		g_index = @title.index(addit)
  		#debugger
  		next if g_index.nil?
  		next if (@title.length - g_index) / @title.length.to_f > ENG_NUM_RATE #如果截取的大于40%
  		@title = @title[0, g_index]
  	end
  	@title 
  end
  
  #清除一些值得怀疑的字符，例如：英文加数字大于4个的字符或者数字>5，需要加强人工审核
  def clear_doubtful()
  	rets = @title.scan(/\w{4,}/i)
  	return @title if rets.nil?
  	rets.each do |ret|
  		next if ret =~ /^[a-zA-z]+$/ #如果是纯英文直接跳过
  		if ret =~ /^\d+$/ and ret.to_s != "2010"
  			@title = @title.gsub(ret, "")	
  		end
			@key_verify = true			
  	end
  	
  	@title = @title.sub(/(\w+$)/i, "")
  	@title = @title.gsub(/(\d+[a-zA-z]+|[a-zA-z]+\d+)/, "")
  	@title
  end
  
  #转换中文数字，全转换成阿拉伯数字
  def invert_number(title = "")
  	ret = title
  	Dict::NUM_MAP.each {|k,v| ret = ret.gsub(k, v)}
  	Dict::ZH_NUM_MAP.each {|k,v| ret = ret.gsub(k, v)}
  	Dict::ZH_NUM_EN_MAP.each {|k,v| ret = ret.gsub(k,v)}
  	return ret
  end
  
  #去除货号 
  def clear_good_no()
  	return title if @good_no.nil?
  	@good_no = clear_special(@good_no)
  	g_index = @title.index(@good_no)
  	#debugger
  	if g_index.nil? #如果未找到货号，截取货号4个字符再查找
  		if @good_no.length > 4
  			g_index = @title.index(@good_no[0,4])
  			@title = sub_good_no(@title, @good_no[0,4], g_index) unless g_index.nil?
  		end
  	else
  		@title = sub_good_no(@title, @good_no, g_index)
  	end
  	@title
  end
  
  #通过正规进行替换
  def replace_by_regexp()
  	Dict::REG_WORDS.each do |reg|
  		reg_str = /#{reg}/i
  		@title = @title.gsub(reg_str, " ")
  	end
  	@title = @title.gsub(/\s+/, " ")
  end
  
  #通过关键词进行替换，优先长词替换
  def replace_by_keyword()
  	Dict::KEY_WORDS.each { |v| @title = @title.gsub(v, "") }
  	@title
  end
  
  #通过nick替换
  def replace_by_nick()
  	return @title unless @nick.index("官方").nil?
  	Dict::NICK_WORDS.each { |v| @nick = @nick.gsub(v, "")	}
  	is_brand = false
  	Dict::BRAND_WORDS.each do |b|
  		if b.downcase.gsub(Dict::BRAND_FILTER_REG, "").include?(@nick.downcase.gsub(Dict::BRAND_FILTER_REG, ""))
				is_brand = true
				break
			end
  	end
  	#puts is_brand
  	@title = @title.gsub(@nick, "") unless is_brand
  	@title
  end
  
  #遇到需要中止的字符，立即退出
  def deal_stop(title = "")
  	ret = false
		Dict::STOP_WORDS.each do |s|
			if title.include? s
				ret = true
				break
			end
	  end
	  ret
  end
  
  #清除未成对的括号
  def clear_no_pairs_punctuation
  	pun_stack = []
  	del_pun = []
  	title_array = to_array(@title)
  	
  	title_array.each_with_index do |t, i|
  		case t
  		when '<', '{', '[', '(', '《', '（'
				pun_stack << {'p' => t, 'l' => i}
			when '>', '}', ']', ')', '》', '）'
				pun_stack << {'p' => t, 'l' => i} if pun_stack.empty?
				if pun_stack.last['p'] == Dict::PUNCTUAION_WORDS[t]
					pun_stack.delete_at(pun_stack.size - 1)
				else
					until pun_stack.empty?
						if pun_stack.last['p'] == Dict::PUNCTUAION_WORDS[t]
							pun_stack.delete_at(pun_stack.size - 1)
							break
						else
							del_pun << pun_stack.last['l']
							pun_stack.delete_at(pun_stack.size - 1)
						end
					end
					
				end
			end
  	end #title_array
  	
  	pun_stack.each {|p| del_pun << p['l']}
		del_pun.each_with_index do |p, i|  	
			if i == 0
				title_array.delete_at(p)
			else
				title_array.delete_at(p.to_i - 1)
			end
		end
		@title = title_array.to_s
  end
  
  #判断英文及数据所占的比例
  def eng_num_rate()
  	ret = @title.match(/[0-9a-zA-Z_!@#%&\$\^\*]+/)
  	return false if ret.nil?
  	return true if (ret[0].length / @title.length.to_f) > ENG_NUM_RATE
  	false
  end
  
  #清除前尾单独的字符
  def clear_start_or_end_punctuation
  	rubs = []
  	Dict::RUBBISH_WORDS.each_char {|r| rubs << r}
  	 
  	title_array = to_array(@title)
  	rubs.each do |r|
  		until title_array.nil?
  			break if title_array.first != r  and title_array.last != r
  			title_array.delete_at(0) if title_array.first == r
  			title_array.delete_at(title_array.size - 1) if title_array.last == r
  		end
  	end
  	@title = title_array.to_s
  end
  
  private
  def sub_good_no(title, good_no, g_index)
  	if (title.length - g_index) / title.length.to_f > ENG_NUM_RATE #如果截取的大于40%
			@key_verify = true
			title = title.gsub(good_no, "")
		else
			title = title[0, g_index]
		end
		title
  end
  
  def to_array(str)
  	return [] if str.nil?
  	
  	ary = []
  	str.each_char {|s| ary << s} 
  	return ary
  end
end
